/**
 * kl yy-ds @2021
 */
package com.cxps.server;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;

/**
 * Java 操作 ES 测试类
 *
 * @author YouCai.Liu
 * @since 2021/11/12
 * ...
 */
@RestController
@RequestMapping("/test")
@Api(tags = "Java操作ES")
public class TestController {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引
     *
     * @return
     */
    @GetMapping("create")
    public String createIndex(String indexName) throws IOException {

        // 创建一个 ES创建索引请求的 对象
        CreateIndexRequest indexRequest = new CreateIndexRequest(indexName);

        // 调用ES客户端提供的方法，进行创建索引
        CreateIndexResponse response = restHighLevelClient.indices().create(indexRequest, RequestOptions.DEFAULT);

        // 进行ACK确认
        boolean acknowledged = response.isAcknowledged();
        return "SUCCESS：" + acknowledged;
    }

    /**
     * 删除索引
     *
     * @return
     */
    @GetMapping("del")
    public String delIndex(String indexName) throws IOException {

        // 创建一个 ES删除索引请求的 对象
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);

        // 调用ES客户端提供的方法，进行创建索引
        AcknowledgedResponse response = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);

        // 进行ACK确认
        boolean acknowledged = response.isAcknowledged();
        return "SUCCESS：" + acknowledged;
    }


    /**
     * 创建索引并设置索引映射
     *
     * @return
     */
    @GetMapping("create2")
    public String createIndex2(String indexName) throws IOException {

        // 创建一个 ES索引请求的 对象
        IndexRequest indexRequest = Requests.indexRequest(indexName);

        // 索引对象
        StudentIndex studentIndex = new StudentIndex();
        studentIndex.setId("1");
        studentIndex.setName("zhangsan");
        studentIndex.setAge(18);
        studentIndex.setBirthday(new Date());
        String[] hobby = {"打游戏", "干饭"};
        studentIndex.setHobby(hobby);
        studentIndex.setFamily(Arrays.asList("兄弟", "姐妹"));

        // 设置文档ID
        indexRequest.id("1");

        // 将对象转换json
        indexRequest.source(JSON.toJSONString(studentIndex), XContentType.JSON);
        indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);

        // 发起请求
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);

        System.out.println(response.status().getStatus());
        System.out.println(response.status().name());

        return "SUCCESS";
    }

    /**
     * 删除索引数据
     *
     * @param id
     * @return
     * @throws IOException
     */
    @GetMapping("/del/{id}")
    public String delById(@PathVariable String id, @RequestParam String indexName) throws IOException {
        // 创建一个删除请求对象
        DeleteRequest request = Requests.deleteRequest(indexName);
        request.id(id);
        DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.status().name());
        return "SUCCESS";
    }

    /**
     * 查询
     *
     * @param indexName
     * @return
     * @throws IOException
     */
    @GetMapping("/search")
    public String search(@RequestParam String indexName) throws IOException {
        // 创建一个搜索请求对象
        SearchRequest searchRequest = Requests.searchRequest(indexName);

        // 创建一个搜索资源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建query条件 QueryBuilders

        // 构建 matchAll 查询
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        // 构建 term 查询
        TermQueryBuilder termQuery = QueryBuilders.termQuery("id", "1");
        // 构建 terms 查询
        TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("id", "1", "2");
        // 构建 wildcard 查询
        WildcardQueryBuilder name = QueryBuilders.wildcardQuery("name", "*ang*");
        // 构建 fuzzy 查询
        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "zhang");

        // 构建组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(matchAllQuery);
        boolQueryBuilder.should(termQuery);

        // 将条件放入查询
        searchSourceBuilder.query(boolQueryBuilder);
        // 分页参数
        searchSourceBuilder.from(0).size(2);
        // 执行搜索
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(hits);
        System.out.println(hits.getHits());
        System.out.println(hits.getHits().length);
        System.out.println(hits.getTotalHits().value);
        return "SUCCESS";
    }

}
